//Class for 4x4 matrices

#ifndef _HELIX_MATRIX_4X4_H_
#define _HELIX_MATRIX_4X4_H_


#include <math.h>
#include "../Helix.h"
#include "../HObject.h"
#include "../Log.h"
#include "Vector.h"

namespace helix
{

	#define H_X_AXIS 0
	#define H_Y_AXIS 1
	#define H_Z_AXIS 2
	#define PI_OVER_180 0.0174532925199

	class MY_CLASS Matrix4x4 : public HObject
	{
	protected:
		double mat[4][4];

	public:
		Matrix4x4();					//create a new matrix (identity)
		Matrix4x4(double mat[4][4]);	//create a matrix from a 2d array of double values
		Matrix4x4(float mat[4][4]);    //create a matrix from a 2d array of float values
		Matrix4x4(double *mat);		//same as above, but from a pointer to the array
		Matrix4x4(double transx,double transy,double transz);	//create a translation matrix
		Matrix4x4(double degrees,int axis);	//create a rotation matrix
		Matrix4x4(double scalex,double scaley,double scalez,double scalefactor); //create a scale matrix
		
		virtual ~Matrix4x4();

		Matrix4x4 operator +  (Matrix4x4 &M);	//overload the + operator to add matrices
		Matrix4x4 operator += (Matrix4x4 &M); //same
		Matrix4x4 operator *  (double &scalar); //multiply matrix by a scalar
		Vector    operator *  (Vector &vector); //multiply matrix by a vector
		Matrix4x4 operator /  (double &scalar);	//divide matrix by a scalar
		virtual Matrix4x4 operator * (Matrix4x4 &M);   //multiply matrix by another matrix
	//	Matrix4x4 operator * (Matrix3x3 M);	//multiply by a 3x3 matrix

		virtual Matrix4x4 Inverse();		//returns the inverse matrix of this matrix
		virtual Matrix4x4 Transpose();		//returns the transpose matrix of this matrix
		virtual Matrix4x4 InverseTranspose();	//returns the inverse transpose of this matrix

		float Determinant();				//returns the matrix's determinant
		float Determinant3x3();				//returns the determinant of the upper left 3x3 matrix's determinant

		void MakeIdentity();   //makes this matrix an identity matrix
		void setRow(int row,Vector vect);	//set a certain row with a vector (leaves mat[row][3] alone)
		void setRow(int row,Vector vect,double last);	//same as above, but lets you set  mat[row][3]
		void setCol(int col,Vector vect);	//set a column with a vector
		void setCol(int col,Vector vect,double last);	//same as above, but lets you set mat[3][col]

		double *getMatrix();

		virtual void Print();
	};

}

#endif


